package org.groupg.practice;

import org.jctools.queues.MpscArrayQueue;

/**
 * 多生产者单消费者
 */
public class MpscExample {
    // 创建一个有界MPSC队列，容量为2048
    private static final MpscArrayQueue<String> queue = new MpscArrayQueue<>(2048);
    private static volatile boolean running = true;

    public static void main(String[] args) throws InterruptedException {
        // 启动消费者线程
        Thread consumer = new Thread(() -> {
            int processedCount = 0;
            while (running || !queue.isEmpty()) {
                String task = queue.poll();
                if (task != null) {
                    processedCount++;
                    // 模拟任务处理
                    System.out.println("Processing: " + task);
                } else {
                    // 没有任务时短暂休眠
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
            System.out.println("Total processed: " + processedCount);
        });
        consumer.start();

        // 启动多个生产者线程
        Thread[] producers = new Thread[4];
        for (int i = 0; i < producers.length; i++) {
            final int producerId = i;
            producers[i] = new Thread(() -> {
                for (int j = 0; j < 500; j++) {
                    String task = "Task-" + producerId + "-" + j;
                    while (!queue.offer(task)) {
                        // 队列满时，生产者可以选择重试、等待或其他策略
                        Thread.yield();
                    }
                }
                System.out.println("Producer " + producerId + " finished");
            });
            producers[i].start();
        }

        // 等待所有生产者完成
        for (Thread producer : producers) {
            producer.join();
        }

        // 通知消费者停止
        running = false;
        consumer.join();
        System.out.println("All done");
    }
}